package com.pureut.order.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pureut.order.domain.ProcurementPlan;
import com.pureut.order.domain.PurchaseOrder;
import com.pureut.order.dto.CustomerSaleRankDto;
import com.pureut.order.dto.PurchaseOrderDto;
import com.pureut.order.dto.PurchaseOrderTraceDto;
import com.pureut.order.mapper.ProcurementPlanDetailMapper;
import com.pureut.order.mapper.PurchaseOrderMapper;
import com.pureut.order.service.ProcurementPlanDetailService;
import com.pureut.order.service.PurchaseOrderService;
import com.pureut.order.vo.*;
import com.sale.common.core.constant.CacheNames;
import com.sale.common.core.exception.GlobalException;
import com.sale.common.mybatis.core.page.PageQuery;
import com.sale.common.mybatis.core.page.TableDataInfo;
import com.sale.common.redis.utils.CacheUtils;
import com.sale.common.redis.utils.RedisUtils;
import com.sale.common.satoken.utils.LoginHelper;
import com.sale.order.api.vo.PurchaseOrderTraceVo;
import com.sale.order.api.vo.UpdatePurchaseOrderDataVo;
import com.sale.storage.api.RemotePurchaseReceiptService;
import com.sale.storage.api.dto.PurchaseOrderTrackDto;
import com.sale.system.api.*;
import com.sale.system.api.domain.SysAuxiliary;
import com.sale.system.api.domain.SysDictData;
import com.sale.system.api.domain.dto.SysCustomDto;
import com.sale.system.api.domain.vo.SysAuditHistoryVo;
import com.sale.system.api.domain.vo.SysWorkbenchAuditAgentDubboVo;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static com.baomidou.mybatisplus.extension.toolkit.Db.updateById;

/**
 * 采购订单实现层
 */
@RequiredArgsConstructor
@Service
public class PurchaseOrderServiceImpl implements PurchaseOrderService {


    private final PurchaseOrderMapper purchaseOrderMapper;


    @DubboReference
    private final RemoteReviewService remoteReviewService;

    @DubboReference
    RemoteCodeService remoteCodeService;

    @DubboReference
    RemotePurchaseReceiptService remotePurchaseReceiptService;

    @DubboReference
    RemoteUnitService remoteUnitService;

    @DubboReference
    RemoteStaffManagementService remoteStaffManagementService;

    @DubboReference
    RemoteWorkbenchMessageService remoteWorkbenchMessageService;


    /**
     * 采购订单列表
     */
    @Override
    public TableDataInfo<Map<String,Object>> getList(PurchaseOrderVo purchaseOrderVo, PageQuery pageQuery) {
        //状态
        List<SysDictData> statusArray = CacheUtils.get(CacheNames.SYS_DICT, "purchase_order_status");
        Map<String, String> statusMap = statusArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        //表名
        String tableName = "`ry-order`.purchase_order";
        //通过缓存获取自定义表头信息
        String userIdStr = LoginHelper.getUserIdStr();
        String tenantId = RedisUtils.getCacheObject(userIdStr);
        List<SysCustomDto> titleMessage = CacheUtils.get(CacheNames.SYS_CUSTOM + "_" + tenantId, tableName);
        StringBuilder stringBuilder = new StringBuilder();
        String code = "";
        Page<Map<String,Object>> purchaseOrderList = null;
        if (titleMessage!= null) {
            for (SysCustomDto entity : titleMessage) {
                stringBuilder.append(",").append("a.").append(entity.getFieldsModel());
            }
            code = stringBuilder.toString();
            purchaseOrderList = purchaseOrderMapper.getPurchaseOrderList(code, pageQuery.build(), purchaseOrderVo);;
        }else {
            purchaseOrderList = purchaseOrderMapper.getPurchaseOrderList(code, pageQuery.build(), purchaseOrderVo);;
        }
        List<Map<String,Object>> list = purchaseOrderList.getRecords();
        for (Map<String, Object> map : list) {
            //辅助属性
            List<SysAuxiliary> statsArray = CacheUtils.get(CacheNames.SYS_GINSENG + "_" + map.get("tenantId"), String.valueOf(map.get("materialId")));
            map.put("auxiliaryAttribute", statsArray);
            //采购计划状态
            map.put("statusDict",statusMap.get(map.get("status").toString()));
            //单位
            if (map.get("materialUnit") != null) {
                String unit = remoteUnitService.getUnitDataByCode(Long.parseLong((String)map.get("materialUnit"))).getData().getUnitName();
                map.put("unitDict",unit);
                map.put("unit",map.get("materialUnit"));
            }
            //物料类别
            if ("1".equals(map.get("materialCategoryDict"))) {
                map.put("materialCategoryDict","原料");
            } else {
                map.put("materialCategoryDict","成品");
            }
            //生成方式
            if ((int)map.get("generationMode") == 1) {
                map.put("generationModeDict","手动生成");
            } else {
                map.put("generationModeDict","自动生成");
            }
            //采购人
            if (map.get("purchaseBy") != null) {
                map.put("purchaseByDict",remoteStaffManagementService.getInfo(Long.parseLong((String)map.get("purchaseBy"))).getData().getStaffName());
            }
        }
//        for (PurchaseOrderDto entity : records) {
//            //辅助属性
//            List<SysAuxiliary> statsArray = CacheUtils.get(CacheNames.SYS_GINSENG + "_" + entity.getTenantId(), String.valueOf(entity.getMaterialId()));
//            entity.setAuxiliaryAttribute(statsArray);
//            //状态
//            entity.setStatusDict(statusMap.get(entity.getStatus()));
//            //单位
//            if (entity.getMaterialUnit() != null) {
//                entity.setUnitDict(remoteUnitService.getUnitDataByCode(Long.parseLong(entity.getMaterialUnit())).getData().getUnitName());
//            }
//            //类别
//            if ("1".equals(entity.getMaterialCategory())) {
//                entity.setCodingRules("原料");
//            } else {
//                entity.setCodingRules("成品");
//            }
//            //生成方式
//            if (entity.getGenerationMode() == 1) {
//                entity.setGenerationModeDict("手动生成");
//            } else {
//                entity.setGenerationModeDict("自动生成");
//            }
//            //采购人
//            if (entity.getPurchaseBy() != null) {
//                entity.setPurchaseByDict(remoteStaffManagementService.getInfo(Long.parseLong(entity.getPurchaseBy())).getData().getStaffName());
//            }
//        }
        return TableDataInfo.build(purchaseOrderList);
    }

    /**
     * 新增
     *
     * @param map
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addOrder(Map<String,Object> map) throws Exception {
        Object materialList1 = map.get("materialList");
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonString = objectMapper.writeValueAsString(materialList1);
        List<PurchaseVo> materialList = JSON.parseArray(jsonString, PurchaseVo.class);

        //表名
        String tableName = "`ry-order`.purchase_order";
        //通过缓存获取自定义表头信息
        String userIdStr = LoginHelper.getUserIdStr();
        String tenantId = RedisUtils.getCacheObject(userIdStr);
        List<SysCustomDto> titleMessage = CacheUtils.get(CacheNames.SYS_CUSTOM + "_" + tenantId, tableName);
        StringBuilder stringBuilder = new StringBuilder();
        String code = "";
        if (titleMessage != null) {
            for (SysCustomDto entity : titleMessage) {
                stringBuilder.append(",").append(entity.getFieldsModel());
            }
            code = stringBuilder.toString();
        }
        Map<String, Object> addMap = new LinkedHashMap<>();
//        List<PurchaseVo> materialList = purchaseOrderVo.getMaterialList();
//        List<PurchaseOrder> purchaseOrderList = new ArrayList<>();
        for (PurchaseVo entity : materialList) {

            addMap.put("purchaseOrderNo", remoteCodeService.authorityCoding("order:purchase:order:list"));
            addMap.put("supplierCode", map.get("supplierCode"));
            addMap.put("billingDate", map.get("billingDate"));
            addMap.put("purchaseContractNo", map.get("purchaseContractNo"));
            addMap.put("remark", map.get("remark"));
            addMap.put("enclosureUrl", map.get("enclosureUrl"));
            addMap.put("createTime", new Date());
            addMap.put("createBy", LoginHelper.getUsername());
            addMap.put("materialCode",entity.getMaterialCode());
            addMap.put("materialUnit", entity.getUnit());
            addMap.put("materialCategory", entity.getMaterialCategory());
            addMap.put("estimatedTime", map.get("estimatedTime"));
            addMap.put("actualUnitPrice", entity.getActualUnitPrice());
            addMap.put("status", 1);
            addMap.put("generationMode", 1);
            addMap.put("actualWeight", Double.parseDouble(entity.getActualWeight()));
            if (titleMessage != null) {
                for (SysCustomDto entity1 : titleMessage) {
                    addMap.put(entity1.getFieldsModel(), map.get(entity1.getFieldsModel()));
                }
            }
//            PurchaseOrder purchaseOrder = new PurchaseOrder();
//            purchaseOrder
//                .setPurchaseOrderNo(remoteCodeService.authorityCoding("order:purchase:order:list"))
//                .setSupplierCode(purchaseOrderVo.getSupplierCode())
//                .setBillingDate(purchaseOrderVo.getBillingDate())
//                .setPurchaseContractNo(purchaseOrderVo.getPurchaseContractNo())
//                .setRemark(purchaseOrderVo.getRemark())
//                .setEnclosureUrl(purchaseOrderVo.getEnclosureUrl())
//                .setCreateTime(new Date())
//                .setCreateBy(LoginHelper.getUsername())
//                .setMaterialCode(entity.getMaterialCode())
//                .setMaterialUnit(entity.getUnit())
//                .setMaterialCategory(entity.getMaterialCategory())
//                .setEstimatedTime(purchaseOrderVo.getEstimatedTime())
//                .setActualUnitPrice(entity.getActualUnitPrice())
//                .setStatus(1)
//                .setGenerationMode(1)
//                .setActualWeight(Double.parseDouble(entity.getActualWeight()));
//            purchaseOrderList.add(purchaseOrder);
        }
        return purchaseOrderMapper.insertMessage(code,addMap);
    }

    /**
     * 新增（采购计划调用）
     *
     * @param purchaseOrderVo
     * @return
     */
    @Override
    public boolean planConfirmation(PurchaseOrderVo purchaseOrderVo) throws Exception {

        PurchaseOrder purchaseOrder = new PurchaseOrder();
        purchaseOrder.setDeptId(LoginHelper.getDeptId());
        //通过采购计划单号拼接采购订单号
        List<String> purchaseNumList = Arrays.asList(purchaseOrderVo.getPurchaseNum().split(","));
        StringBuilder stringBuilder = new StringBuilder();
        for (String entity : purchaseNumList) {
            stringBuilder.append(entity).append(",");
        }
        StringBuilder stringBuilder1 = stringBuilder.deleteCharAt(stringBuilder.length() - 1);
        purchaseOrder.setPurchaseOrderNo(stringBuilder1.toString());

        purchaseOrder.setStatus(1);
        purchaseOrder.setPurchaseOrderNo(remoteCodeService.authorityCoding("order:purchase:order:list"));
        purchaseOrder.setPurchasePlanNo(stringBuilder1.toString());
        purchaseOrder.setMaterialCode(purchaseOrderVo.getMaterialCode());
        purchaseOrder.setPurchaseContractNo(purchaseOrderVo.getPurchaseContractNo());
//        purchaseOrder.setPlanPrice(purchaseOrderVo.getPlannedUnitPrice());
        purchaseOrder.setSupplierCode(purchaseOrderVo.getSupplierCode());
        purchaseOrder.setActualWeight(Double.parseDouble(purchaseOrderVo.getActualWeight()));
        purchaseOrder.setMaterialCategory(purchaseOrderVo.getMaterialCategory());
        purchaseOrder.setCreateBy(LoginHelper.getUsername());
        purchaseOrder.setDemandTime(purchaseOrderVo.getDemandTime());
        purchaseOrder.setEstimatedTime(purchaseOrderVo.getDemandTime());
        purchaseOrder.setMaterialUnit(purchaseOrderVo.getMaterialUnit());
        purchaseOrder.setActualUnitPrice(purchaseOrderVo.getPlannedUnitPrice());
        purchaseOrder.setCreateTime(new Date());
        purchaseOrder.setBillingDate(new Date());
        purchaseOrder.setGenerationMode(2);
        return purchaseOrderMapper.insert(purchaseOrder) > 0;


    }

    /**
     * 采购下单
     *
     * @param purchaseOrderVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateOrder(PurchaseOrderVo purchaseOrderVo) {
        PurchaseOrder purchaseOrder = purchaseOrderMapper.selectById(purchaseOrderVo.getId());
        if (5 == purchaseOrder.getStatus() || 6 == purchaseOrder.getStatus()) {
            purchaseOrder.setPurchaseContractNo(purchaseOrderVo.getPurchaseContractNo())
                .setSupplierCode(purchaseOrderVo.getSupplierCode())
//                .setFirstBatchTime(purchaseOrderVo.getFirstBatchTime())
//                .setEndBatchTime(purchaseOrderVo.getEndBatchTime())
                .setRemark(purchaseOrderVo.getRemark())
                .setEnclosureUrl(purchaseOrderVo.getEnclosureUrl())
                .setActualUnitPrice(purchaseOrderVo.getActualUnitPrice())
                .setActualWeight(Double.parseDouble(purchaseOrderVo.getActualWeight()))
                .setCreateBy(LoginHelper.getUsername())
                .setCreateTime(new Date())
                .setStatus(2);
            return purchaseOrderMapper.updateById(purchaseOrder) > 0;
        } else {
            throw new GlobalException("只能操作待入库和部分入库数据");
        }
    }

    /**
     * 提交审核
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean submitReview(Long id) {
        PurchaseOrder purchaseOrder = purchaseOrderMapper.selectById(id);
        if (1 == purchaseOrder.getStatus()) {
            purchaseOrder.setStatus(2);
            SysWorkbenchAuditAgentDubboVo sysWorkbenchAuditAgentDubboVo = new SysWorkbenchAuditAgentDubboVo();
            sysWorkbenchAuditAgentDubboVo.setDocConfig("order:purchase:order:review");
            sysWorkbenchAuditAgentDubboVo.setReceiptName("采购订单");
            sysWorkbenchAuditAgentDubboVo.setReceiptNumber(purchaseOrder.getPurchaseOrderNo());//供应商编号
            sysWorkbenchAuditAgentDubboVo.setStatus(1);//待审核
            sysWorkbenchAuditAgentDubboVo.setReceiptContent("有单据待审核,请及时审核");

            remoteWorkbenchMessageService.insertAuditAgent(sysWorkbenchAuditAgentDubboVo);

            return purchaseOrderMapper.updateById(purchaseOrder) > 0;
        } else {
            throw new GlobalException("单据状态不为待提交，无法审核");
        }
    }

    /**
     * 撤销审核
     *
     * @param id
     * @return
     */
    @Override
    public boolean deleteReview(Long id) {
        PurchaseOrder purchaseOrder = purchaseOrderMapper.selectById(id);
        if (2 == purchaseOrder.getStatus()) {
            purchaseOrder.setStatus(1);
            //删除审核代办
            remoteWorkbenchMessageService.deleteDoc(purchaseOrder.getPurchaseOrderNo(), "采购订单");
            return purchaseOrderMapper.updateById(purchaseOrder) > 0;
        } else {
            throw new GlobalException("单据状态不为待审核，无法撤销");
        }
    }

    /**
     * 关结
     *
     * @param purchaseOrderVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean closeReview(PurchaseOrderVo purchaseOrderVo) {
        PurchaseOrder purchaseOrder = purchaseOrderMapper.selectById(purchaseOrderVo.getId());
        if (purchaseOrder.getStatus() == 7 || purchaseOrder.getStatus() == 8) {
            throw new GlobalException("不能操作已完成、已关结的单据");
        }
        purchaseOrder.setStatus(8);
        purchaseOrder.setCloseReason(purchaseOrderVo.getCloseReason());
//        //回传关节状态到采购计划明细
//        ProcurementPlanDetail procurementPlanDetail = procurementPlanDetailMapper.selectOne(new QueryWrapper<ProcurementPlanDetail>().lambda().eq(ProcurementPlanDetail::getPurchasementNum, purchaseOrder.getPurchasePlanNo()));
//        procurementPlanDetail.setStatus(5);
//        procurementPlanDetailMapper.updateById(procurementPlanDetail);
        //同步已关结状态至采购入库页面
//        UpdateReceiptStatusVo updateReceiptStatusVo = new UpdateReceiptStatusVo();
//        updateReceiptStatusVo.setPurchaseOrderNo(purchaseOrder.getPurchaseOrderNo());
//        updateReceiptStatusVo.setUpdateValue(4);
//        try {
//            storageFegin.updateReceiptStatus(updateReceiptStatusVo);
//        } catch (Exception e) {
//            throw new GlobalException("采购入库数据修改失败");
//        }
        return purchaseOrderMapper.updateById(purchaseOrder) > 0;
    }

    /**
     * 查看订单信息
     *
     * @param id
     * @return
     */
    @Override
    public Map<String,Object> getViewById(Long id) {
        Map<String, Object> map = new HashMap<>();
        //表名
        String tableName = "`ry-order`.purchase_order";
        //通过缓存获取自定义表头信息
        String userIdStr = LoginHelper.getUserIdStr();
        String tenantId = RedisUtils.getCacheObject(userIdStr);
        List<SysCustomDto> titleMessage = CacheUtils.get(CacheNames.SYS_CUSTOM + "_" + tenantId, tableName);

        Map<String, Object> viewById = purchaseOrderMapper.getViewById(id);
        if (titleMessage != null) {
            for (SysCustomDto entity : titleMessage) {
                if(viewById.get(entity.getFieldsModel()) != null){
                    map.put(entity.getFieldsModel(),viewById.get(entity.getFieldsModel()));
                }
            }
        }

        List<Map<String, Object>> materialVos = new ArrayList<>();
//        MaterialVo materialVo = new MaterialVo();
        Map<String, Object> materialVoMap = new HashMap<>();
        materialVoMap.put("materialCode", viewById.get("materialCode"));
        materialVoMap.put("materialSpec", viewById.get("materialSpec"));
        materialVoMap.put("materialName",viewById.get("bMaterialName"));
        materialVoMap.put("materialPlace",viewById.get("materialPlace"));
        materialVoMap.put("materialId",viewById.get("materialId"));
        materialVoMap.put("actualUnitPrice",viewById.get("actualUnitPrice"));
        materialVoMap.put("actualWeight",viewById.get("actualWeight"));
        //辅助属性
        materialVoMap.put("auxiliaryAttribute",CacheUtils.get(CacheNames.SYS_GINSENG + "_" + viewById.get("tenantId").toString(), String.valueOf(viewById.get("materialId"))));
        materialVoMap.put("unit",viewById.get("materialUnit"));
        materialVoMap.put("unitDict", remoteUnitService.getUnitDataByCode(Long.parseLong(viewById.get("materialUnit").toString())).getData().getUnitName());
        //类别
        if ("1".equals(viewById.get("materialCategory").toString())) {
            materialVoMap.put("materialCategoryDict", "原料");
        } else {
            materialVoMap.put("materialCategoryDict", "成品");
        }
        materialVos.add(materialVoMap);
        map.put("materialList",materialVos);
        map.put("supplierName",viewById.get("supplierName"));
        map.put("supplierCode",viewById.get("supplierCode"));
        map.put("billingDate",viewById.get("billingDate"));
        map.put("purchaseContractNo",viewById.get("purchaseContractNo"));
        map.put("estimatedTime",viewById.get("estimatedTime"));
        map.put("remark",viewById.get("remark"));
        map.put("enclosureUrl",viewById.get("enclosureUrl"));
        map.put("id",viewById.get("id"));
//        materialVo.setMaterialCode(purchaseOrderDto.getMaterialCode());
//        materialVo.setMaterialName(purchaseOrderDto.getMaterialName());
//        materialVo.setMaterialPlace(purchaseOrderDto.getMaterialPlace());
//        materialVo.setMaterialId(purchaseOrderDto.getMaterialId());
//        materialVo.setActualUnitPrice(purchaseOrderDto.getActualUnitPrice());
//        materialVo.setActualWeight(purchaseOrderDto.getActualWeight());
//        materialVo.setMaterialSpec(purchaseOrderDto.getMaterialSpec());
        //辅助属性
//        List<SysAuxiliary> statsArray = CacheUtils.get(CacheNames.SYS_GINSENG + "_" + purchaseOrderDto.getTenantId(), String.valueOf(purchaseOrderDto.getMaterialId()));
//        materialVo.setAuxiliaryAttribute(statsArray);
        //单位
//        materialVo.setUnit(purchaseOrderDto.getMaterialUnit());
//        materialVo.setUnitDict(remoteUnitService.getUnitDataByCode(Long.parseLong(purchaseOrderDto.getMaterialUnit())).getData().getUnitName());
        //类别
//        if ("1".equals(purchaseOrderDto.getMaterialCategory())) {
//            materialVo.setMaterialCategoryDict("原料");
//        } else {
//            materialVo.setMaterialCategoryDict("成品");
//        }
//        materialVos.add(materialVo);
//        purchaseOrderDto.setMaterialList(materialVos);
        return map;
    }

    /**
     * 采购入库
     *
     * @param purchaseOrderDto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchArrival(PurchaseOrderDto purchaseOrderDto) throws Exception {
        PurchaseOrder purchaseOrder = purchaseOrderMapper.selectById(purchaseOrderDto.getId());
        if (purchaseOrder.getStatus() == 5 || purchaseOrder.getStatus() == 6) {
            com.sale.storage.api.dto.PurchaseOrderDto purchaseOrderDto1 = new com.sale.storage.api.dto.PurchaseOrderDto();
            purchaseOrderDto1.setSupplierCode(purchaseOrderDto.getSupplierCode());
            purchaseOrderDto1.setDrawerTime(purchaseOrderDto.getDrawerTime());
            purchaseOrderDto1.setEstimatedTime(purchaseOrderDto.getEstimatedTime());
            purchaseOrderDto1.setMaterialList(purchaseOrderDto.getReceiptList());
            purchaseOrderDto1.setPurchaseContractNo(purchaseOrder.getPurchaseContractNo());
            purchaseOrderDto1.setPurchaseOrderNo(purchaseOrder.getPurchaseOrderNo());
            purchaseOrderDto1.setMaterialCategory(String.valueOf(purchaseOrder.getMaterialCategory()));
            boolean b = remotePurchaseReceiptService.batchArrival(purchaseOrderDto1);
            if (b) {
                purchaseOrder.setEstimatedTime(purchaseOrderDto.getEstimatedTime());
                purchaseOrder.setPurchaseBy(purchaseOrderDto.getPurchaseBy());
                purchaseOrder.setActualUnitPrice(purchaseOrderDto.getReceiptList().get(0).getActualUnitPrice());
                purchaseOrder.setRemark(purchaseOrderDto.getRemark());
                return purchaseOrderMapper.updateById(purchaseOrder) > 0;
            } else {
                return false;
            }
        } else {
            throw new GlobalException("只能操作待到货和批次到货得数据!");
        }
    }


//            //实际到货量-退货量≥下达量时候为已完成,否则改为部分到货
//            BigDecimal add;
//            if (purchaseOrder.getActualArrivalWeight() == 0) {
//                //如果实际到货量为空，必然不满足实际到货量-退货量≥下达量的条件
//                purchaseOrder.setStatus(6);
//                //同步部分到货状态至采购计划
//                ProcurementPlanDetail procurementPlanDetail = procurementPlanDetailMapper.selectOne(new QueryWrapper<ProcurementPlanDetail>().lambda().eq(ProcurementPlanDetail::getPurchasementNum, purchaseOrder.getPurchasePlanNo()));
//                procurementPlanDetail.setStatus(3);
//                procurementPlanDetailService.updateById(procurementPlanDetail);
//            } else {
//                //获取实际到货量
//                add = BigDecimal.valueOf(purchaseOrder.getActualArrivalWeight());
//                //获取退货重量
//                BigDecimal backWeight = BigDecimal.valueOf(purchaseOrder.getBackWeight());
//                //实际到货量-退货量
//                int subtract = (int) Math.round(add.subtract(backWeight).doubleValue());
//                //通过采购计划获取实际量
//                int actualWeight =(int) Math.round(purchaseOrder.getActualWeight());
//
//                if (subtract >= actualWeight) {
//                    purchaseOrder.setStatus(7);
//                    //同步已完成状态至采购入库页面
//                    UpdateReceiptStatusVo updateReceiptStatusVo = new UpdateReceiptStatusVo();
//                    updateReceiptStatusVo.setPurchaseOrderNo(purchaseOrder.getPurchaseOrderNo());
//                    updateReceiptStatusVo.setUpdateValue(3);
//                    storageFegin.updateReceiptStatus(updateReceiptStatusVo);
//                    //同步完成状态至采购计划
//                    ProcurementPlanDetail procurementPlanDetail = procurementPlanDetailMapper.selectOne(new QueryWrapper<ProcurementPlanDetail>().lambda().eq(ProcurementPlanDetail::getPurchasementNum, purchaseOrder.getPurchasePlanNo()));
//                    procurementPlanDetail.setStatus(4);
//                    procurementPlanDetailService.updateById(procurementPlanDetail);
//                } else {
//                    purchaseOrder.setStatus(6);
//                    //同步部分到货状态至采购计划
//                    ProcurementPlanDetail procurementPlanDetail = procurementPlanDetailMapper.selectOne(new QueryWrapper<ProcurementPlanDetail>().lambda().eq(ProcurementPlanDetail::getPurchasementNum, purchaseOrder.getPurchasePlanNo()));
//                    procurementPlanDetail.setStatus(3);
//                    procurementPlanDetailService.updateById(procurementPlanDetail);
//                }


    /**
     * 修改
     *
     * @param map
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateOrderById(Map<String,Object> map) throws JsonProcessingException {
        Long id = Long.valueOf(map.get("id").toString());
        PurchaseOrder purchaseOrder = purchaseOrderMapper.selectById(id);
        if (purchaseOrder.getStatus() == 1 || purchaseOrder.getStatus() == 4) {
            //表名
            String tableName = "`ry-order`.purchase_order";
            //通过缓存获取自定义表头信息
            String userIdStr = LoginHelper.getUserIdStr();
            String tenantId = RedisUtils.getCacheObject(userIdStr);
            List<SysCustomDto> titleMessage = CacheUtils.get(CacheNames.SYS_CUSTOM + "_" + tenantId, tableName);

            Object materialList1 = map.get("materialList");
            ObjectMapper objectMapper = new ObjectMapper();
            String jsonString = objectMapper.writeValueAsString(materialList1);
            List<PurchaseVo> orderList = JSON.parseArray(jsonString, PurchaseVo.class);

            Map<String, Object> updateMap = new LinkedHashMap<>();
//            List<PurchaseVo> orderList = purchaseOrderVo.getMaterialList();
            for (PurchaseVo entity : orderList) {
                updateMap.put("actual_weight",Double.parseDouble(entity.getActualWeight()));
                updateMap.put("actual_unit_price",Double.parseDouble(entity.getActualUnitPrice()));
                updateMap.put("material_unit",entity.getUnit());
                updateMap.put("material_code",entity.getMaterialCode());
//                purchaseOrder.setActualWeight(Double.parseDouble(entity.getActualWeight()));
//                purchaseOrder.setMaterialUnit(entity.getUnit());
//                purchaseOrder.setMaterialCode(entity.getMaterialCode());
            }
            updateMap.put("purchase_contract_no",map.get("purchaseContractNo"));
            updateMap.put("estimated_time",map.get("estimatedTime"));
            updateMap.put("supplier_code",map.get("supplierCode"));
            updateMap.put("remark",map.get("remark"));
            updateMap.put("enclosure_url",map.get("enclosureUrl"));
            updateMap.put("billing_date",map.get("billingDate"));

            if (titleMessage != null) {
                for (SysCustomDto entity1 : titleMessage) {
                    updateMap.put(entity1.getFieldsModel(), map.get(entity1.getFieldsModel()));
                }
            }
//            purchaseOrder.setPurchaseContractNo(purchaseOrderVo.getPurchaseContractNo())
//                .setSupplierCode(purchaseOrderVo.getSupplierCode())
//                .setRemark(purchaseOrderVo.getRemark())
//                .setEnclosureUrl(purchaseOrderVo.getEnclosureUrl());


            //调用审核
            if (purchaseOrder.getStatus() == 4) {
                SysAuditHistoryVo sysAuditHistoryVo = new SysAuditHistoryVo();
                String perms = "order:purchase:order:review";
                String auditDoc = purchaseOrder.getPurchaseOrderNo();
                sysAuditHistoryVo.setAuditDoc(auditDoc);
                sysAuditHistoryVo.setPerms(perms);
                int i = remoteReviewService.editHistory(sysAuditHistoryVo);
                if (i > 0) {
                    purchaseOrder.setStatus(2);
                    //修改审核代办状态为已处理
                    remoteWorkbenchMessageService.updateStatus(3, purchaseOrder.getPurchaseOrderNo(), "采购订单");
                    return purchaseOrderMapper.updateById(purchaseOrder) > 0;
                } else {
                    return false;
                }
            }
            return purchaseOrderMapper.updateProcurementPlan(id,updateMap);
        } else {
            throw new GlobalException("只有待提交和未通过的单据才能进行修改");
        }

    }

    /**
     * 单据审核
     *
     * @param orderReviewVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean purchaseOrderReview(OrderReviewVo orderReviewVo) throws Exception {

        PurchaseOrder purchaseOrder = purchaseOrderMapper.selectById(orderReviewVo.getId());
        if (purchaseOrder.getStatus() == 2 || purchaseOrder.getStatus() == 3) {
            String perms = "order:purchase:order:review";
            int isAdopt = orderReviewVo.getIsAdopt();
            String auditDoc = purchaseOrder.getPurchaseOrderNo();
            String auditRemarks = orderReviewVo.getReviewComments();
            Long userId = LoginHelper.getUserId();
            SysAuditHistoryVo sysAuditHistoryVo = new SysAuditHistoryVo();
            sysAuditHistoryVo.setPerms(perms);
            sysAuditHistoryVo.setModuleType(2);
            sysAuditHistoryVo.setAuditState(isAdopt);
            sysAuditHistoryVo.setAuditRemarks(auditRemarks);
            sysAuditHistoryVo.setAuditDoc(auditDoc);
            sysAuditHistoryVo.setUserId(userId);
            int data = remoteReviewService.getSequence(sysAuditHistoryVo);
            if (data == 0) {
                throw new GlobalException("未对该审核进行配置");
            }
            //1:通过，2：审核中，3：没权限 4:该人已经审核过
            if (orderReviewVo.getIsAdopt() == 1) {
                if (data == 1) {
                    purchaseOrder.setStatus(5);
                    if (purchaseOrder.getReviewBy() == null) {
                        purchaseOrder.setReviewBy(LoginHelper.getUsername());
                    } else {
                        purchaseOrder.setReviewBy(purchaseOrder.getReviewBy() + "," + LoginHelper.getUsername());
                    }
                    purchaseOrder.setReviewTime(new Date());
                    //回传待到货数据到采购计划
//                    ProcurementPlanDetail procurementPlanDetail = procurementPlanDetailMapper.selectOne(new QueryWrapper<ProcurementPlanDetail>().lambda().eq(ProcurementPlanDetail::getPurchasementNum, purchaseOrder.getPurchasePlanNo()));
//                    procurementPlanDetail.setStatus(2);
//                    procurementPlanDetailMapper.updateById(procurementPlanDetail);

                    //修改审核代办状态
                    remoteWorkbenchMessageService.updateStatus(3, purchaseOrder.getPurchaseOrderNo(), "采购订单");

                    return purchaseOrderMapper.updateById(purchaseOrder) > 0;
                } else if (data == 2) {
                    purchaseOrder.setStatus(3);
                    if (purchaseOrder.getReviewBy() == null) {
                        purchaseOrder.setReviewBy(LoginHelper.getUsername());
                    } else {
                        purchaseOrder.setReviewBy(purchaseOrder.getReviewBy() + "," + LoginHelper.getUsername());
                    }
                    purchaseOrder.setReviewTime(new Date());
                    return purchaseOrderMapper.updateById(purchaseOrder) > 0;
                } else if (data == 3) {
                    throw new GlobalException("没有审核权限");
                } else {
                    throw new GlobalException("该用户已经审核过");
                }
            } else {
                if (data == 1 || data == 2) {
                    purchaseOrder.setStatus(4);
                    if (purchaseOrder.getReviewBy() == null) {
                        purchaseOrder.setReviewBy(LoginHelper.getUsername());
                    } else {
                        purchaseOrder.setReviewBy(purchaseOrder.getReviewBy() + "," + LoginHelper.getUsername());
                    }
                    purchaseOrder.setReviewTime(new Date());
                    SysWorkbenchAuditAgentDubboVo sysWorkbenchAuditAgentDubboVo = new SysWorkbenchAuditAgentDubboVo();
                    sysWorkbenchAuditAgentDubboVo.setDocConfig("order:purchase:order:review");
                    sysWorkbenchAuditAgentDubboVo.setReceiptName("采购订单");
                    sysWorkbenchAuditAgentDubboVo.setReceiptNumber(purchaseOrder.getPurchaseOrderNo());//采购订单号
                    sysWorkbenchAuditAgentDubboVo.setStatus(2);//待处理
                    sysWorkbenchAuditAgentDubboVo.setPassFlag("1");
                    sysWorkbenchAuditAgentDubboVo.setCreateName(purchaseOrder.getCreateBy());
                    sysWorkbenchAuditAgentDubboVo.setReceiptContent("有单据未通过,请及时查看");

                    remoteWorkbenchMessageService.insertAuditAgent(sysWorkbenchAuditAgentDubboVo);

                    return purchaseOrderMapper.updateById(purchaseOrder) > 0;
                } else if (data == 3) {
                    throw new GlobalException("没有审核权限");
                } else {
                    throw new GlobalException("该用户已经审核过");
                }
            }
        } else {
            throw new GlobalException("状态为待审核和审核中的单据才能进行审核");
        }
    }

    /**
     * 修改采购订单数据（feign调用）
     *
     * @param updatePurchaseOrderDataVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateOrderData(UpdatePurchaseOrderDataVo updatePurchaseOrderDataVo) {

        //根据采购订单号获取采购订单数据
        PurchaseOrder purchaseOrder = purchaseOrderMapper.selectOne(new QueryWrapper<PurchaseOrder>().lambda().eq(PurchaseOrder::getPurchaseOrderNo, updatePurchaseOrderDataVo.getPurchaseOrderNo()));
        //获取实际到货重量
        double v = Double.parseDouble(updatePurchaseOrderDataVo.getActualQuantity());
        if (purchaseOrder.getActualArrivalWeight() != 0) {
            BigDecimal add = new BigDecimal(String.valueOf(purchaseOrder.getActualArrivalWeight())).add(new BigDecimal(String.valueOf(v)));
            purchaseOrder.setActualArrivalWeight(Double.parseDouble(add.toString()));
        } else {
            purchaseOrder.setActualArrivalWeight(v);
        }
        //如果实际到货量大于等于计划量，就将采购订单改为已完成，否则就改为部分到货
        double actualArrivalWeight = purchaseOrder.getActualArrivalWeight();
        double actualWeight = purchaseOrder.getActualWeight();
        if (actualArrivalWeight >= actualWeight) {
            purchaseOrder.setStatus(7);
        } else {
            purchaseOrder.setStatus(6);
        }
        return purchaseOrderMapper.updateById(purchaseOrder) > 0;
    }

    /**
     * 修改采购订单数据（dubbo调用）扣减重量
     *
     * @param updatePurchaseOrderDataVo
     * @return
     */
    @Override
    public boolean updateOrderDataSub(UpdatePurchaseOrderDataVo updatePurchaseOrderDataVo) {
        //根据采购订单号获取采购订单数据
        PurchaseOrder purchaseOrder = purchaseOrderMapper.selectOne(new QueryWrapper<PurchaseOrder>().lambda().eq(PurchaseOrder::getPurchaseOrderNo, updatePurchaseOrderDataVo.getPurchaseOrderNo()));
        //获取实际到货重量
        double v = Double.parseDouble(updatePurchaseOrderDataVo.getActualQuantity());
        if (purchaseOrder.getActualArrivalWeight() != 0) {
            BigDecimal subtract = new BigDecimal(String.valueOf(purchaseOrder.getActualArrivalWeight())).subtract(new BigDecimal(String.valueOf(v)));
            purchaseOrder.setActualArrivalWeight(Double.parseDouble(subtract.toString()));
        }
        //如果实际到货量扣减之后为0，就修改为待到货
        if (purchaseOrder.getActualArrivalWeight() == 0) {
            purchaseOrder.setStatus(5);
        }
        return purchaseOrderMapper.updateById(purchaseOrder) > 0;
    }

    /**
     * 采购订单退货重量累加
     *
     * @param updatePurchaseOrderDataVo
     * @return
     */
    @Override
    public boolean updateSalesReturn(UpdatePurchaseOrderDataVo updatePurchaseOrderDataVo) {
        //退货重量
        String actualQuantity = updatePurchaseOrderDataVo.getActualQuantity();

        //查询订单重量
        PurchaseOrder purchaseOrder = purchaseOrderMapper.selectOne(new QueryWrapper<PurchaseOrder>().lambda().eq(PurchaseOrder::getPurchaseOrderNo, updatePurchaseOrderDataVo.getPurchaseOrderNo()));

        BigDecimal bigDecimal = new BigDecimal(actualQuantity);

        BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(purchaseOrder.getBackWeight()));

        BigDecimal add = bigDecimal.add(bigDecimal1);
        purchaseOrder.setBackWeight(add.doubleValue());
        boolean b = updateById(purchaseOrder);
        return b;
    }

    /**
     * 修改采购订单退货重量feign扣除
     *
     * @param updatePurchaseOrderDataVo
     * @return
     */
    @Override
    public boolean updateDeductSalesReturn(UpdatePurchaseOrderDataVo updatePurchaseOrderDataVo) {
        //退货重量
        String actualQuantity = updatePurchaseOrderDataVo.getActualQuantity();

        //查询订单重量
        PurchaseOrder purchaseOrder = purchaseOrderMapper.selectOne(new QueryWrapper<PurchaseOrder>().lambda().eq(PurchaseOrder::getPurchaseOrderNo, updatePurchaseOrderDataVo.getPurchaseOrderNo()));

        BigDecimal bigDecimal = new BigDecimal(actualQuantity);

        BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(purchaseOrder.getBackWeight()));

        BigDecimal add = bigDecimal1.subtract(bigDecimal);
        purchaseOrder.setBackWeight(add.doubleValue());

        return updateById(purchaseOrder);
    }

    /**
     * 获取审核过后的（待到货、部分到货）采购订单数据
     */
    @Override
    public TableDataInfo<PurchaseOrderDto> passList(PurchaseOrderVo purchaseOrderVo, PageQuery pageQuery) {
        //状态
        List<SysDictData> statusArray = CacheUtils.get(CacheNames.SYS_DICT, "purchase_order_status");
        Map<String, String> statusMap = statusArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        Page<PurchaseOrderDto> purchaseOrderList = purchaseOrderMapper.getPurchaseOrderPassList(pageQuery.build(), purchaseOrderVo);
        List<PurchaseOrderDto> records = purchaseOrderList.getRecords();
        for (PurchaseOrderDto entity : records) {
            //辅助属性
            List<SysAuxiliary> statsArray = CacheUtils.get(CacheNames.SYS_GINSENG + "_" + entity.getTenantId(), String.valueOf(entity.getMaterialId()));
            entity.setAuxiliaryAttribute(statsArray);
            //状态
            entity.setStatusDict(statusMap.get(entity.getStatus()));
            //单位
            if (entity.getMaterialUnit() != null) {
                entity.setUnitDict(remoteUnitService.getUnitDataByCode(Long.parseLong(entity.getMaterialUnit())).getData().getUnitName());
            }
            //类别
            if ("1".equals(entity.getMaterialCategory())) {
                entity.setCodingRules("原料");
            } else {
                entity.setCodingRules("成品");
            }
            //采购人
            if (entity.getPurchaseBy() != null) {
                entity.setPurchaseByDict(remoteStaffManagementService.getInfo(Long.parseLong(entity.getPurchaseBy())).getData().getStaffName());
            }
        }
        return TableDataInfo.build(purchaseOrderList);
    }

    /**
     * 采购订单数(首页工作台使用)
     *
     * @return
     */
    @Override
    public String getPurchaseOrderNum() {
        SimpleDateFormat sf = new SimpleDateFormat();
        String format = sf.format(new Date());
        return purchaseOrderMapper.getPurchaseOrderNum(format);
    }

    /**
     * 采购订单金额（首页工作台使用）
     *
     * @return
     */
    @Override
    public String getPurchaseOrderPrice() {
        SimpleDateFormat sf = new SimpleDateFormat();
        String format = sf.format(new Date());
        return purchaseOrderMapper.getPurchaseOrderPrice(format);
    }

    /**
     * 前五大供应商采购占比(元)
     *
     * @return
     */
    @Override
    public List<CustomerSaleRankDto> supplierSaleRank() {
        SimpleDateFormat sf = new SimpleDateFormat();
        String format = sf.format(new Date());
        return purchaseOrderMapper.supplierSaleRank(format);
    }

    /**
     * 采购订单追踪列表
     *
     * @param purchaseOrderTraceVo
     * @return
     */
    @Override
    public TableDataInfo<PurchaseOrderTraceDto> purchaseOrderTrace(PurchaseOrderTraceVo purchaseOrderTraceVo, PageQuery pageQuery) {
        //先获取审核通过的数据
        List<PurchaseOrderTraceDto> passList = purchaseOrderMapper.getPassList(purchaseOrderTraceVo);
        //获取采购入库数据
        List<PurchaseOrderTrackDto> purchaseOrderTrackDtos = remotePurchaseReceiptService.purchaseOrderTrackList(purchaseOrderTraceVo);
        //状态
        List<SysDictData> statusArray = CacheUtils.get(CacheNames.SYS_DICT, "purchase_order_status");
        Map<String, String> statusMap = statusArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //循环双列表，如果连个列表中的采购订单号相同，就将数据合并进行返回
        List<PurchaseOrderTraceDto> resultList = new ArrayList<>();
        for (PurchaseOrderTraceDto orderEntity : passList) {
            for (PurchaseOrderTrackDto purchaseOrderEntity : purchaseOrderTrackDtos) {
                if (orderEntity.getPurchaseOrderNo().equals(purchaseOrderEntity.getPurchaseOrderNo())) {
                    PurchaseOrderTraceDto purchaseOrderTraceDto = new PurchaseOrderTraceDto();
                    //辅助属性
                    List<SysAuxiliary> statsArray = CacheUtils.get(CacheNames.SYS_GINSENG + "_" + orderEntity.getTenantId(), String.valueOf(orderEntity.getMaterialId()));
                    purchaseOrderTraceDto
                        //采购订单号
                        .setPurchaseOrderNo(orderEntity.getPurchaseOrderNo())
                        //到货日期
                        .setEstimatedTime(purchaseOrderEntity.getEstimatedTime())
                        //单据状态
                        .setStatus(orderEntity.getStatus())
                        //单据状态
                        .setStatusDict(statusMap.get(orderEntity.getStatus()))
                        //物料编码
                        .setMaterialCode(orderEntity.getMaterialCode())
                        //物料名称
                        .setMaterialName(orderEntity.getMaterialName())
                        //规格
                        .setMaterialSpec(orderEntity.getMaterialSpec())
                        //辅助属性
                        .setAuxiliaryAttribute(statsArray)
                        //供应商名称
                        .setSupplierName(orderEntity.getSupplierName())
                        //计划量
                        .setPlannedWeight(purchaseOrderEntity.getPlannedWeight())
                        //已入库量
                        .setActualQuantity(purchaseOrderEntity.getActualQuantity())
                        //未入库量
                        .setNoWareWeight(purchaseOrderEntity.getNoWareWeight())
                        //采购金额
                        .setPurchasePrice(purchaseOrderEntity.getPurchasePrice())
                        //未入库金额
                        .setNoWareWeightPrice(purchaseOrderEntity.getNoWareWeightPrice())
                        //发票数量
                        .setInvoicedQuantity(purchaseOrderEntity.getInvoicedQuantity())
                        //已开票开金额
                        .setInvoicedAmount(purchaseOrderEntity.getInvoicedAmount())
                        //未开票金额
                        .setNoInvoicedAmount(purchaseOrderEntity.getNoInvoicedAmount());
                    //采购人员
                    if (orderEntity.getPurchaseBy() != null) {
                        purchaseOrderTraceDto.setPurchaseByDict(remoteStaffManagementService.getInfo(Long.parseLong(orderEntity.getPurchaseBy())).getData().getStaffName());
                    }
                    //单位
                    if (orderEntity.getMaterialUnit() != null) {
                        purchaseOrderTraceDto.setUnitDict(remoteUnitService.getUnitDataByCode(Long.parseLong(orderEntity.getMaterialUnit())).getData().getUnitName());
                    }
                    //物料类别
                    if ("1".equals(orderEntity.getMaterialCategory())) {
                        purchaseOrderTraceDto.setMaterialCategoryDict("原料");
                    } else {
                        purchaseOrderTraceDto.setMaterialCategoryDict("成品");
                    }
                    resultList.add(purchaseOrderTraceDto);
                }
            }
        }
        Page<PurchaseOrderTraceDto> page = new Page<>();
        List<PurchaseOrderTraceDto> collect = resultList.stream().skip((long) (pageQuery.getPageNum() - 1) * pageQuery.getPageSize()).limit(pageQuery.getPageSize()).collect(Collectors.toList());
        page.setRecords(collect);
        page.setTotal(resultList.size());
        return TableDataInfo.build(page);
    }

    /**
     * 删除
     *
     * @param ids
     * @return
     */
    @Override
    public int deleteDocument(String ids) {
        if (ids == null) {
            throw new GlobalException("至少选择一条数据");
        }
        List<String> idList = Arrays.asList(ids.split(","));
        List<PurchaseOrder> purchaseOrderList = purchaseOrderMapper.selectList(new QueryWrapper<PurchaseOrder>().lambda()
            .in(PurchaseOrder::getId, idList));
        for (PurchaseOrder entity : purchaseOrderList) {
            if (entity.getStatus() != 1) {
                throw new GlobalException("只能删除待提交得数据");
            }
            if (entity.getGenerationMode() == 2) {
                throw new GlobalException("自动生成得数据不能删除");
            }
        }
        return purchaseOrderMapper.deleteBatchIds(purchaseOrderList);
    }
}
